package admin;

import java.sql.SQLException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Vector;

import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

import utils.Utils;

import model.trivial_pursuit.ListThemes;
import model.trivial_pursuit.Theme;


/**
 * <p>Title: TP_ThemeModel </p>
 *
 * <p>
 * 	Description: Cette classe est le model d'une javax.swing.JTable, elle sert a peupler la Jtable
 *  la table TP_Theme de la BDD  
 * </p>
 *
 * <p>Copyright: (c) 2008 FSSIM</p>
 *
 * <p>Company: FSSImock</p>
 *
 * @author Antoine Farnault
 * @version 1.0
 */
public class TP_ThemeModel extends AbstractTableModel implements TableModel {

	private static final long serialVersionUID = 1L;
	private JTable tableData;
	Vector<Object> rowData = new Vector<Object>(); // Une ligne de la table
	
	private Vector<String> newRow = new Vector<String>();
	private int maxId;
	
	private static final int ID_COL = 0;
	private static final int NAME_COL = 1;
	private static final int BLUE_COL = 2;
	private static final int PINK_COL = 3;
	private static final int YELLOW_COL = 4;
	private static final int GREEN_COL = 5;
	private static final int BROWN_COL = 6;
	private static final int ORANGE_COL = 7;
	
	private static final Integer[] DELETERS = {ID_COL};
	private static final String DELETE_CODE = "delete";

	
	/**
	 * Remplissage de la ligne d'insertion
	 */
	private void initNewBlankRow() {
		this.newRow.add("Nouveau thème :");
		this.newRow.add("Nom du thème");
		this.newRow.add("----");
		this.newRow.add("----");
		this.newRow.add("----");
		this.newRow.add("----");
		this.newRow.add("----");
		this.newRow.add("----");
	}
	
	
	/**
	 * Consutructeur
	 */
	public TP_ThemeModel() {
		super();
		this.maxId = -1;
		try {
			ListThemes lt = new ListThemes();
			lt.connect();
			LinkedList<Theme> themes = lt.readThemes();
			Iterator<Theme> iterator = themes.iterator();
			while (iterator.hasNext()) {
				Theme t = iterator.next();
				if (t.getId()>this.maxId) this.maxId=t.getId();
				rowData.add(t);
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.initNewBlankRow();
		this.newBlankRow();
	}

	
	/**
	 * Sauve la JTable parente
	 * @param jt : JTable parente
	 */
	public void setJTable (JTable jt) {
		this.tableData = jt;
	}
	
	/**
	 * Redefinition de la methode getColumnName de AbstractTableModel
	 * Elle donne automatiquement les noms des colonnes
	 * @param column le numero de colonne dont il faut le nom
	 * @return column le nom de la colonne
	 */
	@Override
	 public  String getColumnName(int column) {
         if (column==ID_COL) return "Numéro";
         if (column==NAME_COL) return "Nom";
         if (column==BLUE_COL) return "Bleu";
         if (column==PINK_COL) return "Rose";
         if (column==YELLOW_COL) return "Jaune";
         if (column==GREEN_COL) return "Vert";
         if (column==BROWN_COL) return "Marron";
         if (column==ORANGE_COL) return "Orange";
         return "";
	 }
	
	/**
	 * Redefinition de la methode getColumnCount de AbstractTableModel
	 * Elle donne le nombre de colonnes de la table
	 * @return le nombre de colonne
	 */
	@Override
	public int getColumnCount() {
		return 8; // il y a 8 colonnes
	}
	
	/**
	 * redefinition de la methode getRowCount de AbstractTableModel
	 * Elle donne automatiquement le nombre de lignes de la table
	 * @return le nombre de lignes
	 */
	@Override
	public int getRowCount() {
		return rowData.size();
	}
	/**
	 * redefinition de la methode getValueAt de AbstractTableModel
	 * Elle donne la valeur d'une cellule de la table
	 * @param i le numero de ligne
	 * @param j le numero de la colonne
	 * @return l'objet a la ligne i et colonne j
	 */
	@Override
	public Object getValueAt(int i, int j) {
//		if (i==0) return newRow.get(j);
		Object o = rowData.get(i);
		if (o instanceof Vector) {
			// 1e ligne (nouvelle entrée)
			return newRow.get(j);
		}
		if (o instanceof Theme) {
			Theme t = (Theme) o;
			if (j == ID_COL) {	// Id
				return t.getId();
			}
			if (j == NAME_COL) {	// Name
				return t.getName();
			}
			if ( j==BLUE_COL ) return t.getColors().get("blue");
			if ( j==PINK_COL ) return t.getColors().get("pink");
			if ( j==YELLOW_COL ) return t.getColors().get("yellow");
			if ( j==GREEN_COL ) return t.getColors().get("green");
			if ( j==BROWN_COL ) return t.getColors().get("brown");
			if ( j==ORANGE_COL ) return t.getColors().get("orange");
		}
		return "Error";
	}
	
	/**
	 * Redefinition de la méthode setValueAt de AbstractTableModel
	 * Elle enregistre la valeur entrée
	 * @param o objet à enregistrer
	 * @param i le numero de ligne
	 * @param j le numero de la colonne
	 */
	@Override
	public void setValueAt(Object o, int i, int j) {
		if (i==0) {
			this.saveNewRow(o);
			return;
		}
		String s = (String) o;
		if ( Utils.inArray( DELETERS, j) && s.equalsIgnoreCase(DELETE_CODE) ) {
			this.deleteRow(i);
			return;
		}
		Theme t = (Theme) this.rowData.get(i);
		if (j==ID_COL) {	// Id
			if (!s.equals("#")) {
				//TODO : vérifier que s est libre, sinon si s<maxId ===> décaller les suivants
				try {
					t.setId(Integer.parseInt(s));
				} catch (NumberFormatException e) {
					// TODO Auto-generated catch block
					System.out.println("Le numero doit être un entier");
					e.printStackTrace();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					System.out.println("Erreur SQL n°"+e.getErrorCode()+": "+e.getSQLState());
					e.printStackTrace();
				} catch (NoSuchFieldException e) {
					// TODO Auto-generated catch block
					System.out.println("Attribut non valide");
					e.printStackTrace();
				}
			}
			return;
		}
		if (j==NAME_COL) {	// Name
			try {
				t.setName(s);
			} catch (NoSuchFieldException e) {
				// TODO Auto-generated catch block
				System.out.println("Attribut non valide");
				e.printStackTrace();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				System.out.println("Erreur SQL n°"+e.getErrorCode()+": "+e.getMessage());
				e.printStackTrace();
			}
			return;
		}
		if ( j>=BLUE_COL && j<=ORANGE_COL ) {	// Color
			try {
				t.setColor(j-BLUE_COL,s);
			} catch (NoSuchFieldException e) {
				// TODO Auto-generated catch block
				System.out.println("Attribut non valide");
				e.printStackTrace();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				System.out.println("Erreur SQL n°"+e.getErrorCode()+": "+e.getMessage());
				e.printStackTrace();
			}
			return;
		}
		
	}

	/**
	 * Ajout d'une ligne dans la table
	 * @param o objet à rajouter
	 */
	public void saveNewRow(Object o) {
		String s = (String) o;
//		Vector<String> row = (Vector<String>) this.rowData.get(0);
		Theme t;
		try {
			t = new Theme();
			t.create(s);
			System.out.println("Ajout à la liste...");
			this.rowData.remove(0);
			this.rowData.add(t);
			// Création d'une nouvelle ligne
			this.newBlankRow();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.tableData.updateUI();
    }
	
	/**
	 * Crée une nouvelle ligne vide en position 0
	 */
	private void newBlankRow() {
//		System.out.println(this.rowData);
		this.rowData.add(0,this.newRow);
	}
	
	/**
	 * Supprime la ligne i
	 * @param i ligne à supprimer
	 */
	public void deleteRow (int i) {
		Theme t = (Theme) this.rowData.get(i);
		try {
			t.delete();
			this.rowData.remove(i);
		} catch (NoSuchFieldException e) {
			System.out.println("Paramètre invalide.");
		} catch (SQLException e) {
			System.out.println("Erreur SQL n°"+e.getErrorCode()+": "+e.getMessage());
		}
		this.tableData.updateUI();
	}
	
	/**
	 * Indique si une case est éditable
	 * @param row		: ligne de la case
	 * @param column	: colonne de la case
	 */
	@Override
	public boolean isCellEditable(int row, int column){
		if (row==0) {
			if (column!=NAME_COL) return false;
		}
		return true;
	}
}
